6. Mutação

1 Diretório

2 Pacotes e dados

library(rio)
library(tidyverse)
library(metan)
# set_wd_here("data")

# dados
maize <- 
  import("examples_data.xlsx",
         sheet = "maize",
         setclass = "tbl")

3 Geral

Fonte: https://dplyr.tidyverse.org/index.html

A função mutate() é utilizada quando se deseja adicionar novas variáveis no conjunto de dados. Estas variáveis são funções de variáveis existentes. Como exemplo, vamos criar uma nova variável chamada CD no conjunto de dados maize, qual será a razão entre CESP e DIES. Note que a função adiciona a nova variável após a última variável origina e mantém todas as demais. Você pode controlar a posição da nova variável criada utilizando os argumentos .before e .after (assim como na função relocate()) e quais variáveis são mantidas utilizando o argumento .keep.

# padrão: nova variável inserida na última posição
maize |>
  mutate(CD = CESP/DIES)
# A tibble: 780 × 11
   AMB   HIB   REP   APLA_PLANT AIES_PLANT  CESP  DIES  MGRA   MMG  NGRA     CD
   <chr> <chr> <chr>      <dbl>      <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl>
 1 A1    H1    I           2.45       2.39  16.9  52.1 228.   375.    NA  0.324
 2 A1    H1    I           2.5        1.43  14.4  50.7 187.   437.   427  0.284
 3 A1    H1    I           2.69       1.52  16.5  54.7 230.   464.   497  0.302
 4 A1    H1    I           2.8        1.64  16.8  52.0 213.   408.   523  0.323
 5 A1    H1    I           2.62       1.55  15.9  51.6 224.   406.   551  0.308
 6 A1    H1    II          2.12       1.8   15    51.4 203.   383.   529  0.292
 7 A1    H1    II          3.15       1.78  10.9  NA    75.2  256.   294 NA    
 8 A1    H1    II          2.97       1.84  15    53.4 204.   387.   528  0.281
 9 A1    H1    II          3.1        1.78  13.6  50.8 187.   348.   538  0.267
10 A1    H1    II          3.02       1.6   16.3  53.9 250.   430.   582  0.302
# ℹ 770 more rows
# posição da nova variável
maize |> mutate(CD = CESP/DIES, 
                 .after = DIES)
# A tibble: 780 × 11
   AMB   HIB   REP   APLA_PLANT AIES_PLANT  CESP  DIES     CD  MGRA   MMG  NGRA
   <chr> <chr> <chr>      <dbl>      <dbl> <dbl> <dbl>  <dbl> <dbl> <dbl> <dbl>
 1 A1    H1    I           2.45       2.39  16.9  52.1  0.324 228.   375.    NA
 2 A1    H1    I           2.5        1.43  14.4  50.7  0.284 187.   437.   427
 3 A1    H1    I           2.69       1.52  16.5  54.7  0.302 230.   464.   497
 4 A1    H1    I           2.8        1.64  16.8  52.0  0.323 213.   408.   523
 5 A1    H1    I           2.62       1.55  15.9  51.6  0.308 224.   406.   551
 6 A1    H1    II          2.12       1.8   15    51.4  0.292 203.   383.   529
 7 A1    H1    II          3.15       1.78  10.9  NA   NA      75.2  256.   294
 8 A1    H1    II          2.97       1.84  15    53.4  0.281 204.   387.   528
 9 A1    H1    II          3.1        1.78  13.6  50.8  0.267 187.   348.   538
10 A1    H1    II          3.02       1.6   16.3  53.9  0.302 250.   430.   582
# ℹ 770 more rows

4 Mutação por grupos

Fonte: https://dplyr.tidyverse.org/index.html

A função group_by() pode ser utilizada para realizar mutação dentro de cada nível de uma ou mais variáveis categóricas. Para este exemplo, vamos criar uma variável (rank) que será o rankeamento das observações dentro de cada híbrido com base na MGRA (em ordem decrescente).

hib <- 
maize |> 
  group_by(HIB, AMB) |>
  mutate(rank = rank(desc(MGRA)))
hib
# A tibble: 780 × 11
# Groups:   HIB, AMB [52]
   AMB   HIB   REP   APLA_PLANT AIES_PLANT  CESP  DIES  MGRA   MMG  NGRA  rank
   <chr> <chr> <chr>      <dbl>      <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1 A1    H1    I           2.45       2.39  16.9  52.1 228.   375.    NA     4
 2 A1    H1    I           2.5        1.43  14.4  50.7 187.   437.   427    13
 3 A1    H1    I           2.69       1.52  16.5  54.7 230.   464.   497     3
 4 A1    H1    I           2.8        1.64  16.8  52.0 213.   408.   523     6
 5 A1    H1    I           2.62       1.55  15.9  51.6 224.   406.   551     5
 6 A1    H1    II          2.12       1.8   15    51.4 203.   383.   529    10
 7 A1    H1    II          3.15       1.78  10.9  NA    75.2  256.   294    15
 8 A1    H1    II          2.97       1.84  15    53.4 204.   387.   528     9
 9 A1    H1    II          3.1        1.78  13.6  50.8 187.   348.   538    12
10 A1    H1    II          3.02       1.6   16.3  53.9 250.   430.   582     2
# ℹ 770 more rows
Tip

Você pode dizer o que o seguinte código retornará?

maize |> 
  group_by(HIB) |> 
  slice_max(MGRA, n = 2)

5 Mutação de várias variáveis

Fonte: https://dplyr.tidyverse.org/reference/across.html

Em alguns casos, deseja-se aplicar a mesma função de mutação (ou resumo) à várias variáveis. A função across() facilita a aplicação da mesma transformação a várias colunas, permitindo que você use a semântica select() dentro de funções como summarise() e mutate(). Como exemplo de aplicação, vamos criar uma função para rescalar uma variável para uma amplitude 0-1 e aplicar essa função à todas as colunas numéricas do conjunto maize.

# função para dividir cada valor por 2
# intervalo de 0 a 1
divid2 <- function(x) {
  x / 2
}

# aplica a função divid2() a todas as colunas numéricas
maize |> mutate(across(where(is.numeric), divid2))
# A tibble: 780 × 10
   AMB   HIB   REP   APLA_PLANT AIES_PLANT  CESP  DIES  MGRA   MMG  NGRA
   <chr> <chr> <chr>      <dbl>      <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1 A1    H1    I           1.23      1.20   8.45  26.1 114.   187.   NA 
 2 A1    H1    I           1.25      0.715  7.2   25.3  93.3  219.  214.
 3 A1    H1    I           1.34      0.76   8.25  27.4 115.   232.  248.
 4 A1    H1    I           1.4       0.82   8.4   26.0 107.   204.  262.
 5 A1    H1    I           1.31      0.775  7.95  25.8 112.   203.  276.
 6 A1    H1    II          1.06      0.9    7.5   25.7 101.   192.  264.
 7 A1    H1    II          1.58      0.89   5.45  NA    37.6  128.  147 
 8 A1    H1    II          1.48      0.92   7.5   26.7 102.   193.  264 
 9 A1    H1    II          1.55      0.89   6.8   25.4  93.6  174.  269 
10 A1    H1    II          1.51      0.8    8.15  27.0 125.   215.  291 
# ℹ 770 more rows
# aplica a função divid2() para algumas colunas
maize |> mutate(across(MGRA:NGRA, divid2, .names = "{.col}_metade"))
# A tibble: 780 × 13
   AMB   HIB   REP   APLA_PLANT AIES_PLANT  CESP  DIES  MGRA   MMG  NGRA
   <chr> <chr> <chr>      <dbl>      <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1 A1    H1    I           2.45       2.39  16.9  52.1 228.   375.    NA
 2 A1    H1    I           2.5        1.43  14.4  50.7 187.   437.   427
 3 A1    H1    I           2.69       1.52  16.5  54.7 230.   464.   497
 4 A1    H1    I           2.8        1.64  16.8  52.0 213.   408.   523
 5 A1    H1    I           2.62       1.55  15.9  51.6 224.   406.   551
 6 A1    H1    II          2.12       1.8   15    51.4 203.   383.   529
 7 A1    H1    II          3.15       1.78  10.9  NA    75.2  256.   294
 8 A1    H1    II          2.97       1.84  15    53.4 204.   387.   528
 9 A1    H1    II          3.1        1.78  13.6  50.8 187.   348.   538
10 A1    H1    II          3.02       1.6   16.3  53.9 250.   430.   582
# ℹ 770 more rows
# ℹ 3 more variables: MGRA_metade <dbl>, MMG_metade <dbl>, NGRA_metade <dbl>

6 Mutação condicional

É muito comum comum que condicionantes sejam necessárias quando alguma nova variável for criada. Abaixo, um pequeno exemplo contendo notas de 10 alunos é utilizado.

set.seed(5)
notas <- 
  data.frame(aluno = paste0("Aluno", 1:10),
             nota = runif(10, 3, 10) |> round(1))
notas
     aluno nota
1   Aluno1  4.4
2   Aluno2  7.8
3   Aluno3  9.4
4   Aluno4  5.0
5   Aluno5  3.7
6   Aluno6  7.9
7   Aluno7  6.7
8   Aluno8  8.7
9   Aluno9  9.7
10 Aluno10  3.8

Os objetivos aqui são:

  1. Criar uma nova variável em notas contendo a classe que tal aluno foi classificado dependendo de sua nota, com as seguintes condições:
    • Nota menor que 4: reprovado
    • Nota de 4 a menos que 7: exame
    • Nota igual ou maior que 7: aprovado
  2. Ordenar as notas em ordem decrescente (do maior para o menor).

case_when() pode ser vista como uma versão vetorizada de ifelse() que permite que você avalie várias instruções. Se nenhum caso corresponder, NA será retornado. Esta função é particularmente útil dentro da função mutate() quando você quer criar uma nova variável que depende de uma combinação complexa de variáveis existentes.

A função é baseada em uma sequência de fórmulas de dois lados. O lado esquerdo (LHS) determina o teste; O lado direito (RHS) fornece o valor de substituição.

notas |> 
  mutate(condicao = case_when(
    nota < 4 ~ "reprovado",
    between(nota, 4, 6.99999999) ~ "exame", # mesmo que nota >= 4 & nota < 7
    TRUE ~ "aprovado" # TRUE: o que não foi incluso nas duas avaliações anteriores
  )) |> 
  arrange(desc(nota))
     aluno nota  condicao
1   Aluno9  9.7  aprovado
2   Aluno3  9.4  aprovado
3   Aluno8  8.7  aprovado
4   Aluno6  7.9  aprovado
5   Aluno2  7.8  aprovado
6   Aluno7  6.7     exame
7   Aluno4  5.0     exame
8   Aluno1  4.4     exame
9  Aluno10  3.8 reprovado
10  Aluno5  3.7 reprovado

Neste exemplo, o conjunto de dados maize é utilizado para mostrar como uma variável qualitativa nominal pode ser criada utilizando a função case_when(). A nova variável será criada dependendo dos valores de APLA, AIES ou CESP. Ao agrupar pela nova variável categórica criada e utilizar a função slice_sample(), um exemplo de cada nível é amostrado aleatoriamente.

set.seed(10)

maize |> 
  mutate(
    CASO = case_when(
      MGRA > 280 | APLA_PLANT < 1.3 | NGRA > 820 ~  "Selecionar",
      APLA_PLANT > 2.3 ~ "Alto",
      MGRA < 130 ~ "Pouco produtivo",
      TRUE ~ "Outro"
    )
  ) |> 
  group_by(CASO) |> 
  slice_sample(n = 1)
# A tibble: 4 × 11
# Groups:   CASO [4]
  AMB   HIB   REP   APLA_PLANT AIES_PLANT  CESP  DIES  MGRA   MMG  NGRA CASO    
  <chr> <chr> <chr>      <dbl>      <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>   
1 A1    H10   III         3.11       1.86  15.5  50.2 194.   405.   479 Alto    
2 A3    H2    II          2.04       0.92  14.7  47.2 130.   362.   360 Outro   
3 A3    H9    I           2.24       1.17  13    42.6  92.6  384.   241 Pouco p…
4 A3    H2    III         0          1.25  17.8  51.6 196.   348.   562 Selecio…